﻿using System;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Text.RegularExpressions;

/// <summary>
/// 字符串扩展类
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// 判断字符串是否为空
    /// </summary>
    /// <param name="s">要判断的字符串</param>
    /// <returns>返回判断结果</returns>
    public static bool IsNullOrEmpty(this string s)
    {
        return string.IsNullOrEmpty(s);
    }
    /// <summary>
    /// 判断字符串是否为Int32
    /// </summary>
    /// <param name="s">要判断的字符串</param>
    /// <returns>返回判断结果</returns>
    public static bool IsInt(this string s)
    {
        int i;
        return int.TryParse(s, out i);
    }
    /// <summary>
    /// 将传入字符串转换为Int32
    /// </summary>
    /// <param name="s">要转换的字符串</param>
    /// <returns>转换结果</returns>
    public static int ToInt(this string s)
    {
        return int.Parse(s);
    }
    /// <summary>
    /// 将字符串按格式输出
    /// </summary>
    /// <param name="format">字符串格式</param>
    /// <param name="args">参数</param>
    /// <returns>格式输出结果</returns>
    public static string FormatWith(this string format, params object[] args)
    {
        return string.Format(format, args);
    }
    /// <summary>
    /// 判断字符串是否符合正则表达式格式
    /// </summary>
    /// <param name="s">要判断的字符串</param>
    /// <param name="regexPattern">正则表达式</param>
    /// <returns>判断结果</returns>
    public static bool IsMatch(this string s, string regexPattern)
    {
        if (s.IsNullOrEmpty())
            return false;
        return Regex.IsMatch(s, regexPattern);
    }
    /// <summary>
    /// 将字符串中匹配正则表达式的部分返回
    /// </summary>
    /// <param name="s">要匹配的字符串</param>
    /// <param name="regexPattern">正则表达式</param>
    /// <returns>返回匹配结果</returns>
    public static string Match(this string s, string regexPattern)
    {
        if (s.IsNullOrEmpty())
            return string.Empty;
        return Regex.Match(s, regexPattern).Value;
    }
    private static readonly Regex NameExpression = new Regex("([A-Z]+(?=$|[A-Z][a-z])|[A-Z]?[a-z]+)", RegexOptions.Compiled);


    /// <summary>
    /// 判断字符串是否有值
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static bool HasValue(this string value)
    {
        return !string.IsNullOrEmpty(value);
    }

    /// <summary>
    /// 判断两个字符串System.Char对象的数值是否相等.
    /// </summary>
    /// <param name="instance">要判断的字符串.</param>
    /// <param name="comparing">要比较的字符串.</param>
    /// <returns>
    /// <c>是</c> 两个字符串的值相等; 否则, <c>否</c>.
    /// </returns>
    public static bool IsCaseSensitiveEqual(this string instance, string comparing)
    {
        return string.CompareOrdinal(instance, comparing) == 0;
    }

    /// <summary>
    /// 判断两个字符串System.Char对象的排序的相对位置是否相等..
    /// </summary>
    /// <param name="instance">要判断的字符串.</param>
    /// <param name="comparing">要比较的字符串.</param>
    /// <returns>
    /// <c>是</c> 两个字符串对象的排序相对位置相等; 否则, <c>否</c>.
    /// </returns>
    public static bool IsCaseInsensitiveEqual(this string instance, string comparing)
    {
        return string.Compare(instance, comparing, StringComparison.OrdinalIgnoreCase) == 0;
    }

    /// <summary>
    /// 压缩字符串.
    /// </summary>
    /// <param name="instance">需要压缩的字符串.</param>
    /// <returns>返回压缩后的字符串</returns>
    public static string Compress(this string instance)
    {
        //Guard.IsNotNullOrEmpty(instance, "instance");

        byte[] binary = Encoding.UTF8.GetBytes(instance);
        byte[] compressed;

        using (var ms = new MemoryStream())
        {
            using (var zip = new GZipStream(ms, CompressionMode.Compress))
            {
                zip.Write(binary, 0, binary.Length);
            }

            compressed = ms.ToArray();
        }

        var compressedWithLength = new byte[compressed.Length + 4];

        Buffer.BlockCopy(compressed, 0, compressedWithLength, 4, compressed.Length);
        Buffer.BlockCopy(BitConverter.GetBytes(binary.Length), 0, compressedWithLength, 0, 4);

        return Convert.ToBase64String(compressedWithLength);
    }

    /// <summary>
    /// 解压字符串.
    /// </summary>
    /// <param name="instance">需要解压的字符串.</param>
    /// <returns>返回解压后的字符串</returns>
    public static string Decompress(this string instance)
    {
        //Guard.IsNotNullOrEmpty(instance, "instance");

        var compressed = Decode(instance);

        if (compressed.Length < 4)
        {
            return string.Empty;
        }

        using (var stream = new MemoryStream())
        {
            var length = BitConverter.ToInt32(compressed, 0);
            stream.Write(compressed, 4, compressed.Length - 4);

            var binary = new byte[length];

            stream.Seek(0, SeekOrigin.Begin);

            using (var zip = new GZipStream(stream, CompressionMode.Decompress))
            {
                try
                {
                    zip.Read(binary, 0, binary.Length);

                    return Encoding.UTF8.GetString(binary);
                }
                catch (InvalidDataException)
                {
                    return string.Empty;
                }
            }
        }
    }

    /// <summary>
    /// 转化字符串为驼峰格式
    /// </summary>
    /// <param name="instance">需要转化的字符串</param>
    /// <returns>返回转化后的字符串</returns>
    public static string ToCamelCase(this string instance)
    {
        //Guard.IsNotNullOrEmpty(instance, "instance");

        return instance[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant() + instance.Substring(1);
    }

    /// <summary>
    /// 根据字符串返回标题部分
    /// </summary>
    /// <param name="value">需要处理的字符串</param>
    /// <returns>返回标题部分</returns>
    public static string AsTitle(this string value)
    {
        if (value == null)
        {
            return string.Empty;
        }

        int lastIndex = value.LastIndexOf(".", StringComparison.Ordinal);

        if (lastIndex > -1)
        {
            value = value.Substring(lastIndex + 1);
        }

        return value.SplitPascalCase();
    }

    /// <summary>
    /// 转换字符串为枚举
    /// </summary>
    /// <param name="value">需要转换的字符串</param>
    /// <param name="defaultValue">需要传化枚举类型值</param>
    /// <typeparam name="T">需要传化枚举类型</typeparam>
    /// <returns>返回转化枚举类型值</returns>
    public static T ToEnum<T>(this string value, T defaultValue)
    {
        if (!value.HasValue())
        {
            return defaultValue;
        }

        try
        {
            return (T)Enum.Parse(typeof(T), value, true);
        }
        catch (ArgumentException)
        {
            return defaultValue;
        }
    }

    /// <summary>
    ///  扩展字符串转化
    /// </summary>
    /// <param name="value">要转化的字符串</param>
    /// <returns>已转化的字符串</returns>
    public static string SplitPascalCase(this string value)
    {
        return NameExpression.Replace(value, " $1").Trim();
    }

    private static byte[] Decode(string value)
    {
        try
        {
            return Convert.FromBase64String(value);
        }
        catch (FormatException)
        {
            return new byte[0];
        }
    }
}


